home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / ADVANCED / TEXTRIM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  5.6 KB  |  286 lines

  1.  
  2. /* textrim.c - by David Blythe, SGI */
  3.  
  4. /* Trimming textures: demonstrates how alpha blending or alpha testing
  5.    can be used to "trim" the shape of textures to arbitrary shapes. 
  6.    Alpha testing is generally cheaper than alpha blending, but
  7.    blending permits antialiased edges. */
  8.  
  9. /* Try: "textrim tree.rgb" where tree.rgb is a SGI .rgb file including
  10.    an alpha component. */
  11.    
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <GL/glut.h>
  15. #include <math.h>
  16. #include "texture.h"
  17.  
  18. static float scale = 1.4;
  19. static float transx, transy, rotx, roty;
  20. static int ox = -1, oy = -1;
  21. static int mot = 0;
  22. #define PAN    1
  23. #define ROT    2
  24.  
  25. void
  26. pan(int x, int y)
  27. {
  28.   transx += (x - ox) / 500.;
  29.   transy -= (y - oy) / 500.;
  30.   ox = x;
  31.   oy = y;
  32.   glutPostRedisplay();
  33. }
  34.  
  35. void
  36. rotate(int x, int y)
  37. {
  38.   rotx += x - ox;
  39.   if (rotx > 360.)
  40.     rotx -= 360.;
  41.   else if (rotx < -360.)
  42.     rotx += 360.;
  43.   roty += y - oy;
  44.   if (roty > 360.)
  45.     roty -= 360.;
  46.   else if (roty < -360.)
  47.     roty += 360.;
  48.   ox = x;
  49.   oy = y;
  50.   glutPostRedisplay();
  51. }
  52.  
  53. void
  54. motion(int x, int y)
  55. {
  56.   if (mot == PAN)
  57.     pan(x, y);
  58.   else if (mot == ROT)
  59.     rotate(x, y);
  60. }
  61.  
  62. void
  63. mouse(int button, int state, int x, int y)
  64. {
  65.   if (state == GLUT_DOWN) {
  66.     switch (button) {
  67.     case GLUT_LEFT_BUTTON:
  68.       mot = PAN;
  69.       motion(ox = x, oy = y);
  70.       break;
  71.     case GLUT_MIDDLE_BUTTON:
  72.       mot = ROT;
  73.       motion(ox = x, oy = y);
  74.       break;
  75.     }
  76.   } else if (state == GLUT_UP) {
  77.     mot = 0;
  78.   }
  79. }
  80.  
  81. void 
  82. afunc(void)
  83. {
  84.   static int state;
  85.   if (state ^= 1) {
  86.     glAlphaFunc(GL_GREATER, .01);
  87.     glEnable(GL_ALPHA_TEST);
  88.   } else {
  89.     glDisable(GL_ALPHA_TEST);
  90.   }
  91. }
  92.  
  93. void 
  94. bfunc(void)
  95. {
  96.   static int state;
  97.   if (state ^= 1) {
  98.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  99.     glEnable(GL_BLEND);
  100.   } else {
  101.     glDisable(GL_BLEND);
  102.   }
  103. }
  104.  
  105. void 
  106. up(void)
  107. {
  108.   scale += .1;
  109. }
  110.  
  111. void 
  112. down(void)
  113. {
  114.   scale -= .1;
  115. }
  116.  
  117. void 
  118. help(void)
  119. {
  120.   printf("Usage: textrim [image]\n");
  121.   printf("'h'            - help\n");
  122.   printf("'a'            - toggle alpha test\n");
  123.   printf("'b'            - toggle blend\n");
  124.   printf("'UP'           - scale up\n");
  125.   printf("'DOWN'         - scale down\n");
  126.   printf("left mouse     - pan\n");
  127.   printf("middle mouse   - rotate\n");
  128. }
  129.  
  130. void 
  131. init(char *filename)
  132. {
  133.   static unsigned *image;
  134.   static int width, height, components;
  135.   if (filename) {
  136.     image = read_texture(filename, &width, &height, &components);
  137.     if (image == NULL) {
  138.       fprintf(stderr, "Error: Can't load image file \"%s\".\n",
  139.         filename);
  140.       exit(1);
  141.     } else {
  142.       printf("%d x %d image loaded\n", width, height);
  143.     }
  144.     if (components != 4) {
  145.       printf("must be an RGBA image\n");
  146.       exit(1);
  147.     }
  148.   } else {
  149.     int i, j;
  150.     unsigned char *img;
  151.     components = 4;
  152.     width = height = 512;
  153.     image = (unsigned *) malloc(width * height * sizeof(unsigned));
  154.     img = (unsigned char *) image;
  155.     for (j = 0; j < height; j++)
  156.       for (i = 0; i < width; i++) {
  157.         int w2 = width / 2, h2 = height / 2;
  158.         if (i & 32)
  159.           img[4 * (i + j * width) + 0] = 0xff;
  160.         else
  161.           img[4 * (i + j * width) + 1] = 0xff;
  162.         if (j & 32)
  163.           img[4 * (i + j * width) + 2] = 0xff;
  164.         if ((i - w2) * (i - w2) + (j - h2) * (j - h2) > 64 * 64 &&
  165.           (i - w2) * (i - w2) + (j - h2) * (j - h2) < 300 * 300)
  166.           img[4 * (i + j * width) + 3] = 0xff;
  167.       }
  168.  
  169.   }
  170.   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  171.   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  172.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  173.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  174.   glTexImage2D(GL_TEXTURE_2D, 0, components, width,
  175.     height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  176.     image);
  177.   glEnable(GL_TEXTURE_2D);
  178.   glMatrixMode(GL_PROJECTION);
  179.   glLoadIdentity();
  180.   gluPerspective(50., 1., .1, 10.);
  181.   glMatrixMode(GL_MODELVIEW);
  182.   glLoadIdentity();
  183.   glTranslatef(0., 0., -5.5);
  184.   glClearColor(.25f, .25f, .25f, .25f);
  185. }
  186.  
  187. void 
  188. display(void)
  189. {
  190.   glClear(GL_COLOR_BUFFER_BIT);
  191.   glPushMatrix();
  192.   glTranslatef(transx, transy, 0.f);
  193.   glRotatef(rotx, 0., 1., 0.);
  194.   glRotatef(roty, 1., 0., 0.);
  195.   glScalef(scale, scale, 0.);
  196.   glBegin(GL_POLYGON);
  197.   glTexCoord2f(0.0, 0.0);
  198.   glVertex2f(-1.0, -1.0);
  199.   glTexCoord2f(1.0, 0.0);
  200.   glVertex2f(1.0, -1.0);
  201.   glTexCoord2f(1.0, 1.0);
  202.   glVertex2f(1.0, 1.0);
  203.   glTexCoord2f(0.0, 1.0);
  204.   glVertex2f(-1.0, 1.0);
  205.   glEnd();
  206.   glPopMatrix();
  207.   glutSwapBuffers();
  208. }
  209.  
  210. void 
  211. reshape(int w, int h)
  212. {
  213.   glViewport(0, 0, w, h);
  214. }
  215.  
  216. /* ARGSUSED1 */
  217. void
  218. key(unsigned char key, int x, int y)
  219. {
  220.   switch (key) {
  221.   case 'A':
  222.   case 'a':
  223.     afunc();
  224.     break;
  225.   case 'B':
  226.   case 'b':
  227.     bfunc();
  228.     break;
  229.   case 'H':
  230.   case 'h':
  231.     help();
  232.     break;
  233.   case '\033':
  234.     exit(0);
  235.     break;
  236.   default:
  237.     break;
  238.   }
  239.   glutPostRedisplay();
  240. }
  241.  
  242. /* ARGSUSED1 */
  243. void
  244. special(int key, int x, int y)
  245. {
  246.   switch (key) {
  247.   case GLUT_KEY_UP:
  248.     up();
  249.     break;
  250.   case GLUT_KEY_DOWN:
  251.     down();
  252.     break;
  253.   default:
  254.     return;
  255.   }
  256.   glutPostRedisplay();
  257. }
  258.  
  259. void
  260. menu(int value)
  261. {
  262.   key((unsigned char) value, 0, 0);
  263. }
  264.  
  265. int 
  266. main(int argc, char **argv)
  267. {
  268.   glutInit(&argc, argv);
  269.   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
  270.   (void) glutCreateWindow("textrim");
  271.   init(argv[1]);
  272.   glutDisplayFunc(display);
  273.   glutKeyboardFunc(key);
  274.   glutSpecialFunc(special);
  275.   glutReshapeFunc(reshape);
  276.   glutMouseFunc(mouse);
  277.   glutMotionFunc(motion);
  278.   glutCreateMenu(menu);
  279.   glutAddMenuEntry("Toggle alpha testing", 'a');
  280.   glutAddMenuEntry("Toggle alpha blending", 'b');
  281.   glutAddMenuEntry("Quit", '\033');
  282.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  283.   glutMainLoop();
  284.   return 0;             /* ANSI C requires main to return int. */
  285. }
  286.